package com.neusoft.neuiotms.common.fixture;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.cache.caching.CacheService;
import com.neusoft.neuiotms.common.converter.DictionaryConverter;
import com.neusoft.neuiotms.common.dto.DictionaryDTO;
import com.neusoft.neuiotms.common.model.Dictionary;
import com.neusoft.neuiotms.common.model.DictionaryType;
import com.neusoft.neuiotms.common.repository.DictionaryRepository;
import com.neusoft.neuiotms.common.repository.DictionaryTypeRepository;
import com.univocity.parsers.annotations.NullString;
import com.univocity.parsers.annotations.Parsed;
import com.univocity.parsers.common.processor.BeanListProcessor;
import com.univocity.parsers.csv.CsvParser;
import com.univocity.parsers.csv.CsvParserSettings;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@Order(value = 2)
public class DictionaryFixture implements CommandLineRunner {

	@Autowired
	private DictionaryTypeRepository dictionaryTypeRepository;
	@Autowired
	private DictionaryRepository dictionaryRepository;
	@Autowired
	private CacheService cacheService;
	@Autowired
	private ApplicationContext applicationContext;
	@Autowired
	private DictionaryConverter dictionaryConverter;

	@Value("${neuiotms.common.dictionay.cache.name:CACHE_COMMON_DIC}")
	public String CACHE_COMMON_DIC;

	@Override
	public void run(final String... args) throws Exception {
		log.info("DCIM 初始化 开始");
		this.initDictionaryType();
		this.initDicCache();
		log.info("DCIM 初始化 结束");

	}

	private void initDicCache() {
		final List<DictionaryType> types = this.dictionaryTypeRepository.findAll();
		final List<Dictionary> list = this.dictionaryRepository.findAll();

		final List<DictionaryDTO> cacheList = new ArrayList<>();
		types.forEach(m -> {
			cacheList.clear();
			list.stream().filter(s -> s.getDictionaryType().getType().equals(m.getType()))
					.map(k -> this.dictionaryConverter.toDTO(k)).forEach(cacheList::add);
			if (!this.cacheService.isInCache(this.CACHE_COMMON_DIC, m.getType())) {
				this.cacheService.put(this.CACHE_COMMON_DIC, m.getType(), cacheList);
			}
		});

	}

	private void initDictionaryType() throws IOException {
		log.info("DCIM初始化字典表数据开始");
		List<DictionaryType> list = this.dictionaryTypeRepository.findAll();
		if (list == null || list.size() == 0) {
			final CsvParserSettings settings = new CsvParserSettings();
			settings.getFormat().setLineSeparator("\n");
			// 可以将解析器配置成自动检测输入中的行分隔符
			settings.setLineSeparatorDetectionEnabled(true);
			settings.setHeaderExtractionEnabled(true);

			final BeanListProcessor<DictionaryTypeBean> processor = new BeanListProcessor<>(DictionaryTypeBean.class);
			settings.setProcessor(processor);

			final CsvParser parser = new CsvParser(settings);
			final org.springframework.core.io.Resource csvFile = this.applicationContext
					.getResource("classpath:fixture/neuiot_dictionary_type.csv");

			if (!csvFile.exists()) {
				return;
			}
			parser.parse(csvFile.getInputStream());
			final List<DictionaryTypeBean> typeBeans = processor.getBeans();
			final List<DictionaryBean> dictionarys = this.initDictionary();

			final List<Dictionary> saveList = new ArrayList<>();
			for (final DictionaryTypeBean typeBean : typeBeans) {
				final DictionaryType setting = new DictionaryType();
				BeanUtils.copyProperties(typeBean, setting);
				final DictionaryType model = this.dictionaryTypeRepository.save(setting);
				final List<DictionaryBean> everyTypedictionary = dictionarys.stream()
						.filter(t -> t.getDictionary_type_id() == typeBean.getId()).collect(Collectors.toList());
				final List<Dictionary> dictionary = everyTypedictionary.stream().map(k -> {
					final Dictionary d = new Dictionary();
					BeanUtils.copyProperties(k, d);
					d.setDictionaryType(model);
					return d;
				}).collect(Collectors.toList());
				saveList.addAll(dictionary);
			}

			if (!saveList.isEmpty()) {
				this.dictionaryRepository.saveAll(saveList);
			}
		}

		log.info("初始化字典表数据结束");
	}

	private List<DictionaryBean> initDictionary() throws IOException {
		final CsvParserSettings dictionarySettings = new CsvParserSettings();
		dictionarySettings.getFormat().setLineSeparator("\n");
		// 可以将解析器配置成自动检测输入中的行分隔符
		dictionarySettings.setLineSeparatorDetectionEnabled(true);
		dictionarySettings.setHeaderExtractionEnabled(true);

		final BeanListProcessor<DictionaryBean> dictionaryprocessor = new BeanListProcessor<>(DictionaryBean.class);
		dictionarySettings.setProcessor(dictionaryprocessor);

		final CsvParser parser1 = new CsvParser(dictionarySettings);
		final org.springframework.core.io.Resource csvDictionaryFile = this.applicationContext
				.getResource("classpath:fixture/neuiot_dictionary.csv");

		if (!csvDictionaryFile.exists()) {
			return new ArrayList<>();
		}

		parser1.parse(csvDictionaryFile.getInputStream());
		return dictionaryprocessor.getBeans();
	}

	@Getter
	@Setter
	@ToString
	public static class DictionaryTypeBean {
		@Parsed(field = "id")
		private Long id;

		@Parsed(field = "text")
		private String text;

		@Parsed(field = "type")
		private String type;

	}

	@Getter
	@Setter
	@ToString
	public static class DictionaryBean {
		@Parsed(field = "id")
		private Long id;

		@Parsed(field = "code")
		private String code;

		@NullString(nulls = { "null" })
		@Parsed(field = "sort")
		private Integer sort;

		@Parsed(field = "text")
		private String text;

		@Parsed(field = "dictionary_type_id")
		private Long dictionary_type_id;

	}

}
